Add cpufreq sanity check
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 9 Mar 2010 09:59:59 +0000 (09:59 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 9 Mar 2010 09:59:59 +0000 (09:59 +0000)
This fixes bug 1585 http://bugzilla.xensource.com/bugzilla/show_bug.cgi?id=3D1585

root cause: with incorrect BIOS info, cpufreq driver may not start. in
this case, if user use xenpm to manipulate cpufreq driver, NULL
pointer will cause xen panic. this patch add the sanity check and
warning info to fix this issue.

Signed-off-by: Yu Ke <ke.yu@intel.com>
xen/drivers/cpufreq/cpufreq.c
xen/drivers/cpufreq/cpufreq_ondemand.c

index 7ef193a987dd289368c30e4e9c2527eadddf2f5f..5524bc92a66c8f10158ce3aa90329012645ae4fc 100644 (file)
@@ -177,6 +177,15 @@ int cpufreq_add_cpu(unsigned int cpu)
             processor_pminfo[firstcpu]->perf.domain_info.coord_type) ||
             (perf->domain_info.num_processors !=
             processor_pminfo[firstcpu]->perf.domain_info.num_processors)) {
+
+            printk(KERN_WARNING "cpufreq fail to add CPU%d:"
+                   "incorrect _PSD(%"PRIu64":%"PRIu64"), "
+                   "expect(%"PRIu64"/%"PRIu64")\n",
+                   cpu, perf->domain_info.coord_type,
+                   perf->domain_info.num_processors,
+                   processor_pminfo[firstcpu]->perf.domain_info.coord_type,
+                   processor_pminfo[firstcpu]->perf.domain_info.num_processors
+                );
             return -EINVAL;
         }
     }
@@ -193,6 +202,7 @@ int cpufreq_add_cpu(unsigned int cpu)
         ret = cpufreq_driver->init(policy);
         if (ret) {
             xfree(policy);
+            cpufreq_cpu_policy[cpu] = NULL;
             return ret;
         }
         printk(KERN_EMERG"CPU %u initialization completed\n", cpu);
index c30e8346dbf9269848820bfd00b044a9657a2085..e85bcdf45d2b2ed4d9d562df197ad32c3e71f560 100644 (file)
@@ -286,6 +286,12 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event)
         break;
 
     case CPUFREQ_GOV_LIMITS:
+        if ( this_dbs_info->cur_policy == NULL )
+        {
+            printk(KERN_WARNING "CPU%d ondemand governor not started yet,"
+                    "unable to GOV_LIMIT\n", cpu);
+            return -EINVAL;
+        }
         if (policy->max < this_dbs_info->cur_policy->cur)
             __cpufreq_driver_target(this_dbs_info->cur_policy,
                 policy->max, CPUFREQ_RELATION_H);